package net.towee.server.rpc.services;


import java.util.List;
import java.util.Map;

import net.towee.client.siowrapper.Push;
import net.towee.model.account.AccountData;
import net.towee.model.account.AccountGroup;
import net.towee.model.account.AccountIdentity;
import net.towee.model.account.AccountProfile;
import net.towee.model.account.Board;
import net.towee.model.account.ContactsGroup;
import net.towee.model.account.Gadget;
import net.towee.model.account.Role;
import net.towee.model.discussion.Discussion;
import net.towee.model.discussion.DiscussionSubject;
import net.towee.model.discussion.Message;
import net.towee.model.group.GroupData;
import net.towee.model.group.GroupEnterRequest;
import net.towee.model.group.GroupIdentity;
import net.towee.model.group.GroupProfile;
import net.towee.model.repo.AttachmentIdentity;
import net.towee.model.repo.AttachmentInfo;
import net.towee.model.repo.DocumentData;
import net.towee.model.repo.DocumentIdentity;
import net.towee.model.repo.DocumentPatch;
import net.towee.model.repo.DocumentType;
import net.towee.model.repo.NodeData;
import net.towee.model.utils.Pair;
import net.towee.shared.exceptions.NameExistsException;
import net.towee.shared.exceptions.PersistenceException;

import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;

/**
 * Request/Response services
 * 
 * @author c58
 */
@RemoteServiceRelativePath("/socket.io")
public interface ToweeService extends SocketIOService {
	/*
	 * Request/Response methods
	 */
	AccountData getCurrentAccount();

	AccountProfile getAccountProfile(String accountId) throws PersistenceException;

	AccountIdentity getAccountIdentity(String accountId) throws PersistenceException;

	boolean checkAccountWithNicknameExists(String nickname);

	boolean updateAccountIdentity(AccountIdentity identity) throws PersistenceException;

	boolean updateAccountProfile(AccountProfile profile) throws PersistenceException;

	boolean putSetting(String key, String val);

	boolean updateSettings(Map<String, String> settingsMap);
	
	AttachmentIdentity createAttachmentIdentity(String rawAttachmentId) throws PersistenceException;
	
	AttachmentInfo getAttachmentInfo(String attachmentId) throws PersistenceException;
	
	ContactsGroup createContactsGroup(String name);
	
	boolean removeContactsGroup(String id);
	
	boolean renameContactsGroup(String id, String newName);
	
	boolean addContactsToGroup(String id, List<AccountIdentity> accounts) throws PersistenceException;

	boolean removeContactsForomGroup(String id, List<String> accountIds) throws PersistenceException;
	
	Board addBoard(Board board);
	
	boolean removeBoard(String boardId) throws PersistenceException;
	
	boolean renameBoard(String boardId, String newName) throws PersistenceException;

	GroupIdentity attachGroupToBoard(String boardId, String groupId) throws PersistenceException;
	
	boolean detachGroupFromBoard(String boardId, String groupId);
	
	Discussion getDiscussion(String id, DiscussionSubject subject, int offset, int limit) throws PersistenceException;
	
	String addDiscussionMessage(String discId, DiscussionSubject subject, Message mess) throws PersistenceException;
	
	boolean changeDiscussionMessage(String discId, DiscussionSubject subject, Message mess) throws PersistenceException;
	
	List<DocumentData> findDocument(String str, List<String> groupId, String authorId,
			List<DocumentType> type, int offset, int limit);
	
	List<DocumentData> getDocuments(List<String> groupId, List<DocumentType> types, int offset,
			int limit);
	
	DocumentData getDocuments(String docId) throws PersistenceException;
	
	DocumentData saveDocument(DocumentData doc, String parentNodeId) throws NameExistsException, PersistenceException;
	
	DocumentData changeDocument(DocumentData doc, String explain) throws NameExistsException;
	
	boolean tupDocument(String docId) throws PersistenceException;
	
	Map<String, DocumentPatch> getDocumentPatchs(List<String> neededPatchs) throws PersistenceException;
	
	GroupData getGroupData(String id) throws PersistenceException;
	
	List<GroupProfile> findGroup(String str, int offset, int limit);
	
	List<Pair<AccountIdentity, AccountGroup>> getGroupMembers(String groupId, int offset, int limit);

	List<AccountIdentity> whosOnline(String groupId, int offset, int limit);

	List<GroupProfile> getGroupsByIds(List<String> ids);

	boolean addEnterRequest(String groupId, String accountId, String testAnsw) throws PersistenceException;

	boolean processEnterRequest(String groupId, String accountId) throws PersistenceException;

	List<GroupEnterRequest> getEnterRequests(String groupId, int offset, int limit);

	GroupData createGroup(GroupData group) throws PersistenceException, NameExistsException;

	AccountGroup enterToGroup(String groupId, String testAnswer) throws PersistenceException;
	
	boolean leaveGroup(String groupId) throws PersistenceException;

	boolean kickUserFromGroup(String groupId, String userId) throws PersistenceException;
	
	boolean updateGroupProfile(GroupProfile groupProfile);
	
	boolean updatePrintName(String groupId, String newName);
	
	String getGroupTestQuestion(String groupId) throws PersistenceException;
	
	List<NodeData> getRootNodes(String groupId);
	
	List<NodeData> getSubTree(String groupId, String parentNodeId);

	List<NodeData> getSubTreeByPath(String groupId, String path);

	List<NodeData> getSubTreeToPath(String groupId, String path) throws PersistenceException;

	NodeData getNode(String nodeId) throws PersistenceException;

	NodeData saveNode(NodeData node) throws PersistenceException;

	boolean moveNodes(String groupId, String newParentNode, List<String> nodeIds) throws PersistenceException;

	boolean renameNode(String groupId, String nodeId, String newName) throws PersistenceException;

	boolean putToTrash(String groupId, List<String> nodeIds) throws PersistenceException;
	
	boolean removeNode(String groupId, List<String> nodeIds) throws PersistenceException;
	
	boolean checkNodeExisting(String nodeName, String groupNode, String parentNode);
	
	void updateBoard(Board currentBoard) throws PersistenceException;
	
	List<AccountIdentity> findAccount(String str, int offset, int limit);
	
	Gadget attachGadgetToBoard(String boardId, Gadget g);
	
	boolean detachGadgetFromBoard(String boardId, String gadgetId);
	
	int getRecentDocumentsCount(List<String> groupId, List<DocumentType> types) throws PersistenceException;
	
	boolean updateGadget(String boardId, Gadget g) throws PersistenceException;
	
	boolean updateGroupTestQuest(String id, String quest, String questAnswer);
	
	boolean applyRoleToUser(String roleId, String userId, String groupId) throws PersistenceException;
	
	void setDefaultRole(String groupId, Role role);
	
	List<GroupProfile> getAllGroup(int offset, int limit);

	boolean sendFeedback(String userName, String message);
	
	String updateCookieId();

	/*
	 * Push methods 
	 */
	@Push AccountIdentity onAccountIdentityUpdated(AccountIdentity retult, String node);
	
	@Push AccountProfile onAccountProfileUpdated(AccountProfile result, String node);

	@Push Pair<String, Boolean> onOnlineStateChanged(Pair<String, Boolean> result, String node);

	@Push Pair<AccountIdentity, String> onUserAddedToContacts(Pair<AccountIdentity, String> result, String node);

	@Push Pair<AccountIdentity, String> onUserRemovedFromContacts(Pair<AccountIdentity, String> result,
			String node);

	@Push Pair<String, Message> onDiscussionMessageUpdate(Pair<String, Message> result, String node);

	@Push DocumentData onDocumentUpdate(DocumentData doc, String node);

	@Push List<DocumentIdentity> onDocumentDelete(List<DocumentIdentity> identity, String node);

	@Push Pair<AccountIdentity, DocumentIdentity> onDocumentRated(
			Pair<AccountIdentity, DocumentIdentity> result, String node);

	@Push GroupIdentity onUserLeaveFromGroup(GroupIdentity result, String node);

	@Push AccountGroup onUserEnterToGroup(GroupIdentity result, String node);

	@Push List<NodeData> onNodesRemoved(List<NodeData> nodes, String node);

	@Push List<NodeData> onNodesChange(List<NodeData> treeNode, String node);

	@Push List<NodeData> onNodesToTrash(List<String> nodeIds, String node);

	@Push Pair<String, List<NodeData>> onNodesMoved(Pair<String, List<NodeData>> result, String node);

	@Push Pair<Role, String> onUserRoleUpdated(Pair<Role, String> result, String node);
}
